Execute Python from within current file
Inspired by VimTip608. To execute Python from a range within the current text file and write the output to that file (replacing the Python), add the snippet below to vimrc (or other suitable *rc file). Requires a 'proper' Python setup so that the imported modules can be found. I find it a handy intermediate step between using the Python interpreter on command line and running a complete script. Can be used for easy buffer manipulation, filtering input, preprocessing text and templating-like tasks. python << EOL import vim, StringIO,sys def PyExecReplace(line1,line2): r = vim.current.buffer.range(int(line1),int(line2)) redirected = StringIO.StringIO() sys.stdout = redirected exec('\n'.join® + '\n') sys.stdout = sys.__stdout__ output = redirected.getvalue().split('\n') r: = output:-1 # the -1 is to remove the final blank line redirected.close() EOL command -range Pyer python PyExecReplace(,) Some examples of use Simple print 2 + 2 :Pyer With the cursor on the 'print' line, that line is replaced with 4. Filter for line in vim.current.buffer: if line0 != '\t': print line :%Pyer Filters out lines beginning with a tab in the current buffer. Inserting time import time print time.ctime() :%Pyer Replaces line with date/time. Getting web content without tags import urllib2,htmllib,formatter h = htmllib.HTMLParser(formatter.AbstractFormatter(formatter.DumbWriter())) h.feed(urllib2.urlopen('http://www.somesite.com').read()) :%Pyer Inserts the web page text, but not the html tags, for a given site. Comments I use the following: "in vimrc: "python extensions py from vim import buffers, windows, command, current, error py import vim, sys py from vimpy import * command! PyExecBuffer py exec('\n'.join(current.buffer)) map :PyExecBuffer imap a vimpy.py import sys, vim class Buffer: def __init__(self,buf): self.buf=buf def write(self,s): ll=s.split('\n') self.buf-1+=ll0 for l in ll1:: self.buf.append(l) def clear(self): del self.buf: def redirect(buf=None): buf = buf or vim.current.window.buffer try: sys._stdout except: sys._stdout=sys.stdout sys.stdout = Buffer(buf) Then I start Vim, create new window ( N), and do :py redirect(current.window.buffer) on a window I want to receive all printed data. Then in any buffer executes the buffer contents in Python, output goes to the window selected. To redirect output back just do sys.stdout = sys._stdout = Simpler version = This does not require python support in vim. Select lines using V and then press F5. :vnoremap :!python source. This one saves the current file before execution and does come back without PAUSE (tested in windows) noremap :w:silent execute "!python %" Run Python samples from Vim ---- " >>> Play Python from within gVim " >>> useful to copy/paste samples and run inside Vim " >>> usage Normal_ against a Python block " >>> Visual_ on Visual Python block " >>> Insert_, automatically add print() " if has('python') || has('python3') " nnz_ :let @/=@_ nnZz :let pyf=tempname() \:sil!let python=has('python3')?'py3file ':'pyfile ' \:sil!let yank = substitute(@0,'>.\{3}\s\=','','g') \:sil!call writefile(split(yank,'\n'),pyf) \:sil!redir @"sil!exe 'silent!'.python.pyf:redir ENDp nm yip}Zz xm :yZz im :s/\(>.\{3}\s\=\)\=\(.*\)/\1print(\2)z_ " -------------------------------------------- endif # example insert mode, as calculator, 1/2 # example anywhere inside block help(help) # example anywhere inside block >>> # Fibonacci series: ... # the sum of two elements defines the next ... a, b = 0, 1 >>> while b < 10: ... print(b) ... a, b = b, a+b ... 1 1 2 3 5 8